/**   
* @Title: ClassPathScanUtil.java
* @Package com.jbeer.framework.utils
* @author Bieber
* @date 2014年6月1日 上午11:11:59
* @version V1.0   
*/

package com.jbeer.framework.utils;

import java.io.File;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.net.JarURLConnection;
import java.net.URL;
import java.net.URLDecoder;
import java.util.Enumeration;
import java.util.HashSet;
import java.util.Set;
import java.util.jar.JarEntry;
import java.util.jar.JarFile;

import org.apache.log4j.Logger;

/**
* <p>类功能说明:扫描classpath下的文件工具类</p>
* <p>类修改者	    修改日期</p>
* <p>修改说明</p>
* <p>Title: ClassPathScanUtil.java</p>
* @author Bieber <a mailto="bieber.jbeer@hotmail.com">bieber.jbeer@hotmail.com</a>
* @date 2014年6月1日 上午11:11:59
* @version V1.0
*/

public class ClassPathScanFileUtil {

    
    private static final Logger logger = LoggerUtil.generateLogger(ClassPathScanFileUtil.class);
    /**
     * 
    * <p>函数功能说明:扫描所有classpath文件方法</p>
    * <p>Bieber  2014年6月1日</p>
    * <p>修改者名字 修改日期</p>
    * <p>修改内容</a>  
    * @return Set<String>
     */
    public static Set<String> scanClassPathFile(String path, String extendName, boolean isFullPath)
                                                                                                throws IOException {
        if(logger.isDebugEnabled()){
            logger.debug("starting scan dir "+path+" find "+extendName+" file");
        }
        Set<String> filePaths = new HashSet<String>();
        String classPathDirPath = URLDecoder.decode(Thread.currentThread().getContextClassLoader()
            .getResource("").getPath(), "UTF-8");

        Enumeration<URL> urls = Thread.currentThread().getContextClassLoader().getResources(path);
        path = classPathDirPath + path;
        path = path.replaceAll("\\/", "").replaceAll("\\\\", "");
        while (urls.hasMoreElements()) {
            URL url = urls.nextElement();
            String protocol = url.getProtocol();
            if ("file".equals(protocol) || "vfs".equals(protocol)) {
                String filePath = URLDecoder.decode(url.getFile(), "UTF-8");
                if(filePath.indexOf(".jar")!=-1){
                    JarFile jar = new JarFile(filePath.substring(0, filePath.indexOf(".jar")+4));
                    scanJarFile(jar,isFullPath,filePaths,extendName);
                }else{
                findAndAddClassesInPackageByFile(filePaths, classPathDirPath, filePath, path,
                    extendName, isFullPath);
                }
            } else if ("jar".equals(protocol)) {
                JarFile jarFile = ((JarURLConnection) url.openConnection()).getJarFile();
                scanJarFile(jarFile,isFullPath,filePaths,extendName);
            }
        }
        return filePaths;
    }

    /**
     * 
    * <p>函数功能说明:扫描jar包下面的内容</p>
    * <p>Bieber  2014年6月1日</p>
    * <p>修改者名字 修改日期</p>
    * <p>修改内容</a>  
    * @return void
     */
    private static void scanJarFile(JarFile jarFile,boolean isFullPath,Set<String> filePaths,String extendName){
        String jarName = jarFile.getName();
        jarName = jarName.replaceAll("\\"+File.separator, "");
        Enumeration<JarEntry> entries = jarFile.entries();
        while (entries.hasMoreElements()) {
            JarEntry entry = entries.nextElement();
            String name = entry.getName();
            if (name.endsWith(extendName)) {
                if(!isFullPath){
                    filePaths.add(name); 
                }else{
                filePaths.add(jarFile.getName()+name);
                }
               }
        }
    }
    
    /**
     * 
    * <p>函数功能说明:扫描包下面的文件</p>
    * <p>Bieber  2014年6月1日</p>
    * <p>修改者名字 修改日期</p>
    * <p>修改内容</a>  
    * @return void
     */
    private static void findAndAddClassesInPackageByFile(Set<String> filePaths,
                                                         String classPathDirPath, String filePath,
                                                         String basePath, String extendName,
                                                         boolean isFullPath)
                                                                         throws UnsupportedEncodingException {
        File rootFile = new File(filePath);
        if (rootFile.exists()) {
            if (rootFile.isDirectory()) {
                File[] files = rootFile.listFiles();
                for (File file : files) {
                    findAndAddClassesInPackageByFile(filePaths, classPathDirPath,
                        URLDecoder.decode(file.getPath(), "UTF-8"), basePath, extendName, isFullPath);
                }
            } else {
                classPathDirPath = new File(classPathDirPath).getPath() + "\\";
                String tempPath = filePath.replaceAll("\\" + File.separator, "");
                if (tempPath.startsWith(basePath)) {
                    if (filePath.endsWith(extendName)) {
                        if (!isFullPath) {
                            filePaths.add(filePath.replace(classPathDirPath, ""));
                        } else {
                            filePaths.add(filePath);
                        }
                    }
                }
            }
        }
    }
}
